
package com.roomio.util;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.FileNameMap;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

public class FileUtil {
	private static final Logger log = LoggerFactory.getLogger(FileUtil.class);

	/**
	 * Default constuctor
	 */
	public FileUtil() {
	}

	/**
	 * Reads a file storing intermediate data into a list. Fast method.
	 * 
	 * @param file
	 *            the file to be read
	 * @return a file data
	 * @throws IOException
	 */
	public static byte[] readToList(String file) throws IOException {
		InputStream in = null;
		byte[] buf = null; // output buffer
		int bufLen = 20000 * 1024;
		try {
			in = new BufferedInputStream(new FileInputStream(file));
			buf = new byte[bufLen];
			byte[] tmp = null;
			int len = 0;
			List data = new ArrayList(24); // keeps peaces of data
			while ((len = in.read(buf, 0, bufLen)) != -1) {
				tmp = new byte[len];
				System.arraycopy(buf, 0, tmp, 0, len); // still need to do copy
				data.add(tmp);
			}
			/*
			 * This part os optional. This method could return a List data for
			 * further processing, etc.
			 */
			len = 0;
			if (data.size() == 1)
				return (byte[]) data.get(0);
			for (int i = 0; i < data.size(); i++)
				len += ((byte[]) data.get(i)).length;
			buf = new byte[len]; // final output buffer
			len = 0;
			for (int i = 0; i < data.size(); i++) { // fill with data
				tmp = (byte[]) data.get(i);
				System.arraycopy(tmp, 0, buf, len, tmp.length);
				len += tmp.length;
			}
		} finally {
			if (in != null)
				try {
					in.close();
				} catch (Exception e) {
				}
		}
		return buf;
	}

	/**
	 * Reads a file storing intermediate data into an array.
	 * 
	 * @param file
	 *            the file to be read
	 * @return a file data
	 */
	public static byte[] readToArray(String file) throws IOException {
		InputStream in = null;
		byte[] out = new byte[0];
		try {
			in = new BufferedInputStream(new FileInputStream(file));
			out = readToArray(in);
		} finally {
			// always close the stream
			if (in != null)
				try {
					in.close();
				} catch (Exception e) {
				}
		}
		return out;
	}

	public static byte[] readToArray(InputStream in) throws IOException {
		byte[] out = new byte[0];
		try {
			// the length of a buffer can vary
			int bufLen = 20000 * 1024;
			byte[] buf = new byte[bufLen];
			byte[] tmp = null;
			int len = 0;
			while ((len = in.read(buf, 0, bufLen)) != -1) {
				// extend array
				tmp = new byte[out.length + len];
				// copy data
				System.arraycopy(out, 0, tmp, 0, out.length);
				System.arraycopy(buf, 0, tmp, out.length, len);
				out = tmp;
				tmp = null;
			}
		} finally {
			// always close the stream
			if (in != null)
				try {
					in.close();
				} catch (Exception e) {
				}
		}
		return out;
	}

	/**
	 * Creates a big file with given name
	 * 
	 * @param file
	 *            the file name
	 */
	public static void writeToFile(String file, byte[] bytes) throws Exception {
		IOUtils.write(bytes,new FileOutputStream(file));
	}

	public static void writeToFile(OutputStream out, byte[] bytes) throws Exception {
		IOUtils.write(bytes, out);
	}

	public static void writeToFile(String fileName, String contents) throws Exception {
		PrintWriter pw = new PrintWriter(fileName);
		pw.println(contents);
		pw.close();
	}

	// ////////////////// Helper methods ////////////////////
	public static File readFile(String path) {
		File file = null;
		try {
			org.springframework.core.io.Resource resource = new ClassPathResource(path);
			file = resource.getFile();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return file;
	}

	public static String readFileContentsPath(String path) {
		String contents = null;
		try {
			contents = FileUtils.readFileToString(new File(path));
		} catch (IOException ex) {
			ex.printStackTrace();
		}
		return contents;
	}

	public static String readFileContents(String path) {
		StringBuffer sb = new StringBuffer();
		String contents = null;
		try {
			contents = FileUtils.readFileToString(readFile(path));
		} catch (IOException ex) {
			ex.printStackTrace();
		}
		return contents;
	}

	public static URL getResourceFromClasspath(String path) {
		ClassLoader loader = ClassLoader.getSystemClassLoader();
		URL url = loader.getResource(path);
		return url;
	}

	public static URI getResourceURI(String path) throws Exception {
		Resource resource = new ClassPathResource(path);
		return resource.getURI();
	}

	private static FileNameMap fileNameMap = URLConnection.getFileNameMap();
	
	public static String getMimeType (String path){
		return fileNameMap.getContentTypeFor(path);
	}
	
}
